#ifndef ANIMATEDMODEL_H_INCLUDED
#define ANIMATEDMODEL_H_INCLUDED

#include <stdexcept>
#include <fstream>
#include <sstream>

#include "../math/vec3.h"

#include "model.h"

using std::stringstream;
using std::ifstream;

namespace sheeplib {

    namespace model {
		struct ModelAnimation {
			string m_Name;
			float m_StartTime;
			float m_EndTime;
		};
				
        class AnimatedModel : public Model {
        	private:
				ModelFrame 	m_InterpolatedFrame; ///Stores the current position of the model based on animTime

				string m_CurrentAnimation;
				string m_NextAnimation;

				float m_CurrentAnimationTime;
				float m_CurrentAnimationEndTime;
				float m_FPS;
				vector<ModelAnimation> 	m_Animations;

				struct Finder {
					Finder(const string &name)
					: m_ID(name)
					{
					}

					bool operator()(const ModelAnimation& m)
					{
						return m.m_Name == m_ID;
					}

					string m_ID;
				};

			protected:
				int FindAnimation(const string& name) const;
				virtual bool LoadModelFile(const string& filename) = 0;
                virtual void Update(float dT) = 0;
                virtual void SetAnimationTime(float time);
                
                ModelFrame& GetInterpolatedFrame();
                const ModelFrame& GetInterpolatedFrame() const;
                
                const float GetAnimTime() const;
				void SetAnimation(const string& name);
				void SetNextAnimation(const string& name);
				void MoveNextAnimation();
				const string GetCurrentAnimation() const;
				void SetFPS(float v);
				bool LoadAnimationFile(const string& filename);
				const float GetAnimEndTime() const;
				vector<ModelAnimation>& GetAnimations();
				void IncrementCurrentAnimationTime(float dT);
				
            public:
                AnimatedModel():
                m_CurrentAnimationTime(0.0) {

                }

                virtual ~AnimatedModel() {

                }

				///Returns a list of the possible animations that can be set
				const vector<string> slListAnimations() const;
				
				/// Sets the next animation to name (if it exists) otherwise
				/// will throw a logic_error
				void slSetNextAnimation(const string& animationName);
				void slSetAnimation(const string& animationName);
				bool slLoadAnimationFile(const string& filename);
        };
    }
}

#endif // ANIMATEDMODEL_H_INCLUDED
